package com.um.springboot.starter.orm.manager;

import com.um.springboot.starter.entity.Page;
import com.um.springboot.starter.orm.entity.BaseDTO;
import com.um.springboot.starter.orm.entity.BaseEntity;
import com.um.springboot.starter.orm.entity.BaseVO;
import com.um.springboot.starter.orm.entity.Response;
import com.um.springboot.starter.orm.params.*;
import com.um.springboot.starter.orm.service.BaseEntityService;
import com.um.springboot.starter.utils.ReflectUtil;
import com.um.springboot.starter.utils.UMBeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;


/**
 * @author 邓南辉
 * 日期 2023/2/6
 * 版权所有 广州优匠科技有限公司
 */
@Slf4j
public class BasePlusManager<S extends BaseEntityService<E>,E extends BaseEntity,D extends BaseDTO,V extends BaseVO,P extends PageDTO,L extends ListDTO> extends BaseManager<S> {


    protected Class<E> entityClass = this.getEntityClass();
    protected Class<D> dtoClass = this.getDTOClass();
    protected Class<V> voClass = this.getVOClass();

    protected Class<E> getEntityClass() {
        Type superclass = getClass().getGenericSuperclass();
        ParameterizedType type = (ParameterizedType) superclass;
        return (Class<E>) type.getActualTypeArguments()[1];
    }


    protected Class<D> getDTOClass() {
        Type superclass = getClass().getGenericSuperclass();
        ParameterizedType type = (ParameterizedType) superclass;
        return (Class<D>) type.getActualTypeArguments()[2];
    }

    protected Class<V> getVOClass() {
        Type superclass = getClass().getGenericSuperclass();
        ParameterizedType type = (ParameterizedType) superclass;
        return (Class<V>) type.getActualTypeArguments()[3];
    }

    /**
     * 查询一个列表
     */
    public Response<List<E>> list(L listDTO){

        ListParams params = listDTO.toListParams();

        List<E> list;
        if(params.getRangeEntitys().size() > 0) {
            list = service.getListByLike(params.getProperties(), params.getValues(),params.getRangeEntitys(),params.getOrderNames(),params.getSortOns());
        }else{
            list = service.getListByLike(params.getProperties(), params.getValues(),params.getOrderNames(),params.getSortOns());
        }

        return Response.success(list);
    }

    /**
     * 查询分页列表
     */
    public Response<Page<E>> page(P pageDTO){
        PageParams params = pageDTO.toPageParams();

        Page<E> page = new Page<>();
        page.setPageNo(params.getPageNo());
        page.setPageSize(params.getPageSize());

        if(params.getRangeEntitys().size() > 0) {
            page = service.getPage(page, params.getProperties(), params.getValues(),params.getRangeEntitys(),params.getOrderNames(),params.getSortOns());
        }else{
            page = service.getPage(page, params.getProperties(), params.getValues(),params.getOrderNames(),params.getSortOns());
        }
        return Response.success(page);
    }

    /**
     * 查询一个对象
     */
    public Response<V> get(String id){
       E entity = service.getEntity(id);
       V vo = UMBeanUtils.copyBean(entity,voClass);
       return Response.success(vo);
    }

    /**
     * 保存一个对象,如果对象存在就更新，不存在就插入
     *
     * @param dto 属性和值
     * @return 执行成功返回true
     */
    public Response save(D dto){
        E entity = UMBeanUtils.copyBean(dto,entityClass);
        return Response.success(service.save(entity));
    }


    /**
     * 保存一个对象,如果对象存在就更新，不存在就插入
     *
     * @param dto 属性和值
     * @return 返回保存后的实体Map
     */
    public Response<E> saveEntity(D dto){
        E entity = UMBeanUtils.copyBean(dto,entityClass);
        return Response.success(service.saveEntity(entity));
    }

    /**
     * 保存多个对象列表
     *
     * @param list 对象列表
     */
    public Response saveList(List<D> list){
        List<E> list1 = UMBeanUtils.copyBeanList(list,entityClass);
        boolean result = service.saveList(list1);
        return result ? Response.success() : Response.failed();
    }

    /**
     * 增加一个对象
     *
     * @param dto 实体Map
     */
    public Response<E> addEntity(D dto){
        E entity = UMBeanUtils.copyBean(dto,entityClass);
        return Response.success(service.addEntity(entity));
    }

    /**
     * 更改一个对象
     *
     * @param dto 实体Map
     */
    public Response<E> updateEntity(String id,D dto){
        E entity = service.getEntity(id);
        BeanUtils.copyProperties(dto,entity);
        return Response.success(service.updateEntity(entity));
    }

    /**
     * 删除一个实体
     * @param id
     * @return
     */
    public Response delete(String id){
        boolean result = service.delete(id);
        return result ? Response.success() : Response.failed();
    }

    /**
     * 根据id列表删除对象
     *
     * @param ids     值数组
     * @return 执行成功返回true
     */
    public Response deleteIds(List<String> ids){
        boolean result = service.deleteIds(ids);
        return result ? Response.success() : Response.failed();
    }


    /**
     * 启用或停用
     * @param id
     * @param enable
     * @return
     */
    public Response enable(String id, String enable) {
        E entity = service.getEntity(id);
        //AssertX.exist(entity);

        ReflectUtil.setValue(entity,"isEnable",enable);
        boolean result = service.update(entity);
        return result ? Response.success() : Response.failed();
    }

    /**
     * 调整排序
     * @param id
     * @param sortNo
     * @return
     */
    public Response sort(String id, int sortNo) {
        E entity = service.getEntity(id);
        //AssertX.exist(entity);

        ReflectUtil.setValue(entity,"sortNo",sortNo);
        boolean result = service.update(entity);
        return result ? Response.success() : Response.failed();
    }

    /**
     * 导出Excel
     * @param exportParams
     * @return
     */
    public Response exportPage(ExportParams exportParams){
        return Response.success(service.exportPage(exportParams));
    }


}
